#===================================================#
#           CMakeLists.txt -- rootFolder
#===================================================#

#---------------------------------------------------#
#                cmake version
#---------------------------------------------------#
cmake_minimum_required(VERSION 3.1)
message( STATUS "cmake: ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" )


#---------------------------------------------------#
#                    OS
#---------------------------------------------------#
if( APPLE )
    option( _OS_MACOSX_ " MACOSX " ON )
    option( _OS_UNIX_ " UNIX " ON )
    message( STATUS "___APPLE___" )

elseif( UNIX AND NOT APPLE )
    option( _OS_LINUX_ " LINUX " ON )
    option( _OS_UNIX_ " UNIX " ON )
    message( STATUS "___UNIX___" )

elseif( WIN32 )
    option( _OS_WIN32_ " WIN32 " ON )
    message( STATUS "___WIN32___" )

endif( APPLE )


#-- c++11
set (CMAKE_CXX_STANDARD 11)

set (CMAKE_CXX_STANDARD_REQUIRED ON)
set (CMAKE_CXX_EXTENSIONS OFF)


#---------------------------------------------------#
#                project name
#---------------------------------------------------#
set ( PROJ_NAME breakout)
project ( ${PROJ_NAME} )


#-- *** test: 0.1 ***
set ( VERSION_MAJOR 0 )
set ( VERSION_MINOR 1 )

set ( APP_NAME ${PROJ_NAME})


#---------------------------------------------------#
#                   build/publish/
#---------------------------------------------------#
#-- change finally exe out-path: build/publish
set (EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/publish)

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/publish)

# 确认一些 变量值：
message(STATUS "[__INFO__] CMAKE_BINARY_DIR: ${CMAKE_BINARY_DIR}")
message(STATUS "[__INFO__] PROJECT_BINARY_DIR: ${PROJECT_BINARY_DIR}")
message(STATUS "[__INFO__] CMAKE_RUNTIME_OUTPUT_DIRECTORY: ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")


#---------------------------------------------------#
#                 Sysconfig
#---------------------------------------------------#
option( SWITCH_1
    " option test: switch 1 " ON )
option( CONSOLE_LOG
    " use console as logger, set OFF if use file instead" ON)
configure_file(
    "${CMAKE_CURRENT_SOURCE_DIR}/config/config.h.in"
    "${EXECUTABLE_OUTPUT_PATH}/config/config.h"
)


#---------------------------------------------------#
#                    src (.cpp/.c)
#---------------------------------------------------#

FILE(GLOB_RECURSE   SOURCE_FILES   
                    ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp
                    ${CMAKE_CURRENT_SOURCE_DIR}/src/*.c
                    )

#---------------------------------------------------#
#                   App
#---------------------------------------------------#

if( ${CMAKE_VERSION} VERSION_GREATER 3.16 )
    set ( CMAKE_UNITY_BUILD_BATCH_SIZE 16 ) # 10 ～ 20
endif()


add_executable( ${APP_NAME} ${SOURCE_FILES} )


#-- set libs/dlls output-name --> "${APP_NAME}.xxx"
set_target_properties(${APP_NAME} PROPERTIES PREFIX "")
set_target_properties(${APP_NAME} PROPERTIES OUTPUT_NAME "${APP_NAME}")


if( ${CMAKE_VERSION} VERSION_GREATER "3.16.0" )
    target_precompile_headers( ${APP_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/_pch_/pch.h ) # PCH
    set_target_properties( ${APP_NAME} PROPERTIES UNITY_BUILD ON) # UNITY
endif()


#---------------------------------------------------#
#                   include  （.h/.hpp）
#---------------------------------------------------#

# macro(): find all .h/.hpp files used in this project 
MACRO( collect_head_dirs return_list )
    FILE(GLOB_RECURSE   new_list 
                        ${CMAKE_CURRENT_SOURCE_DIR}/src/*.h
                        ${CMAKE_CURRENT_SOURCE_DIR}/src/*.hpp
                        )
    SET(dir_list "")
    FOREACH(file_path ${new_list})
        GET_FILENAME_COMPONENT(dir_path ${file_path} PATH)
        SET(dir_list ${dir_list} ${dir_path})
    ENDFOREACH()
    LIST(REMOVE_DUPLICATES dir_list)
    SET(${return_list} ${dir_list})
ENDMACRO()

# call macro
collect_head_dirs( src_header_dirs )

# show how many header files are found
list(LENGTH src_header_dirs src_header_dirs_count )
message(STATUS "[__INFO__] Found ${src_header_dirs_count} header directories.")



# ===== set include directories =====
target_include_directories ( ${APP_NAME} PUBLIC

    # === create by cmake ===
    ${EXECUTABLE_OUTPUT_PATH}/config

    # === 3-rd party libs ===
    ${CMAKE_CURRENT_SOURCE_DIR}/deps/spdlog
    ${CMAKE_CURRENT_SOURCE_DIR}/deps/rapidjson
    ${CMAKE_CURRENT_SOURCE_DIR}/deps/sqlite.3.28
    ${CMAKE_CURRENT_SOURCE_DIR}/deps/box2d2.4.0/include
    # ...

    # === headers used in this project ===
    ${CMAKE_CURRENT_SOURCE_DIR}/src
    ${CMAKE_CURRENT_SOURCE_DIR}/src/_pch_

    ${src_header_dirs}
    )
# -- avoid 3-rd parrty .h warings --
target_include_directories ( ${APP_NAME} SYSTEM PUBLIC
    ${CMAKE_CURRENT_SOURCE_DIR}/deps
    ${CMAKE_CURRENT_SOURCE_DIR}/deps/glm.9.9.5
    ${CMAKE_CURRENT_SOURCE_DIR}/deps/stb_image
    ${CMAKE_CURRENT_SOURCE_DIR}/deps/glad
    
    )


#---------------------------------------------------#
#             subdirectory CMakeLists.txt
#---------------------------------------------------#
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/deps/glad)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/deps/sqlite.3.28)

# box2d avoid test
set(BOX2D_BUILD_UNIT_TESTS OFF CACHE BOOL "" FORCE)
set(BOX2D_BUILD_TESTBED OFF CACHE BOOL "" FORCE)
set(BOX2D_BUILD_DOCS OFF CACHE BOOL "" FORCE)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/deps/box2d2.4.0)



# -- SDL2 --
if ( UNIX )
    target_include_directories ( ${APP_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/deps/SDL2-2.0.12/include)
    set(SDL_SHARED OFF CACHE BOOL "" FORCE)
    set(SDL_TEST OFF CACHE BOOL "" FORCE)
    add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/deps/SDL2-2.0.12)
endif( UNIX )

if ( MSVC )
target_include_directories ( ${APP_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/deps/SDL2-2.0.12/prebuild/include)
endif ( MSVC )


#---------------------------------------------------#
#             target_link_libraries
#---------------------------------------------------#
target_link_libraries( ${APP_NAME}
                        SQLite
                        glad
                        box2d
                        )

if ( UNIX )
target_link_libraries( ${APP_NAME}
                        SDL2-static
                        SDL2main
                        )
endif( UNIX )  

if( MSVC )
    target_link_libraries( ${APP_NAME} 
                            ${CMAKE_CURRENT_SOURCE_DIR}/deps/SDL2-2.0.12/prebuild/lib/x64/SDL2main.lib
                            ${CMAKE_CURRENT_SOURCE_DIR}/deps/SDL2-2.0.12/prebuild/lib/x64/SDL2.lib
                            )
endif( MSVC )


# post-build operation
file(GLOB RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/resources/*)
file(COPY ${RESOURCES} DESTINATION ${EXECUTABLE_OUTPUT_PATH}/resources)

if( MSVC)
    file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/deps/SDL2-2.0.12/prebuild/lib/x64/SDL2.dll DESTINATION ${EXECUTABLE_OUTPUT_PATH}/)
endif( MSVC )